package framework.server.cfg;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;

public class ServicesCfgHandler extends AbstractCfgHandler {
	
	private ServiceCfg serviceCfg;
	private ParamCfg paramCfg; 
	private List<ServiceCfg> serviceCfgs;

	public ServicesCfgHandler() {
		super();
		serviceCfgs = new ArrayList<ServiceCfg>();
	}
	
	public void parseURI(File file) {
		serviceCfgs.clear();
		super.parseURI(file);
	}

	public List<ServiceCfg> getServiceCfgs() {
		return serviceCfgs;
	}

	private void startElementServices() {
	}

	private void endElementServices() {
	}

	private void startElementService(Attributes attributes) {
		String serviceName = attributes.getValue("name");
		String className = attributes.getValue("class");
		String pathName = attributes.getValue("path");
		String jarName = attributes.getValue("jar");
		boolean shouldRunnig = (attributes.getValue("runnig") == null) || 
				attributes.getValue("runnig").equalsIgnoreCase("true");
		serviceCfg = new ServiceCfg(serviceName, className, pathName, jarName, shouldRunnig);
	}

	private void endElementService() {
		/** Assuming the document is valid, then when we parse </service>,
 		 * we know we've got a service name and class name to print out */
		System.out.println("parsed " + serviceCfg);
		serviceCfgs.add(serviceCfg);
		serviceCfg = null;
	}

	private void startElementInit() {
		serviceCfg.setParams(new ArrayList<ParamCfg>());
	}

	private void endElementInit() {
	}

	private void startElementParam(Attributes attributes) {
		if (attributes.getValue("name") != null) { 
			/** name-value pair */
			String paramName = attributes.getValue("name");
			String paramVal = attributes.getValue("value");
			paramCfg = new ParamValueCfg(paramName, paramVal);
		} else if (attributes.getValue("list") != null) {
			String paramName = attributes.getValue("list");
			String paramVal = attributes.getValue("value");
			paramCfg = serviceCfg.getParam(paramName);
			if (paramCfg == null) {
				paramCfg = new ParamListCfg(paramName, paramVal);
			} else {
				((ParamListCfg) paramCfg).add(paramVal);
			}
		} else if (attributes.getValue("map") != null) {
			String paramName = attributes.getValue("map");
			String paramKey = attributes.getValue("key");
			String paramVal = attributes.getValue("value");
			paramCfg = serviceCfg.getParam(paramName);
			if (paramCfg == null) {
				paramCfg = new ParamMapCfg(paramName, paramKey, paramVal);
			} else {
				((ParamMapCfg) paramCfg).put(paramKey, paramVal);
			}
		}
	}

	private void endElementParam() {
		/** After </param>, we've got the param name and value */
		System.out.println("parsed " + paramCfg);
		serviceCfg.addParam(paramCfg);
		paramCfg = null;
	}

	/**
	 * Every time the parser encounters the beginning of a new element, it
	 * calls this method, which resets the string buffer
	 */
	@Override
	public void startElement(String uri, String localName, String name, Attributes attributes) {
		accumulator.setLength(0); /** Ready to accumulate new text */
		if (name.equals("services")) {
			startElementServices();
		} else if (name.equals("service")) {
			/** If its a service tag, look for attributes */
			startElementService(attributes);
		} else if (name.equals("init")) {
			startElementInit();
		} else if (name.equals("param")) {
			startElementParam(attributes);
		}
	}

	/**
	 * When the parser encounters the end of an element, it calls this method
	 */
	@Override
	public void endElement(String uri, String localName, String name) {
		if (name.equals("services")) {
			endElementServices();
		} else if (name.equals("service")) {
			endElementService();
		} else if (name.equals("init")) {
			endElementInit();
		} else if (name.equals("param")) {
			endElementParam();
		}
	}

	public void print() {
	}

	public static void main(String args[]) {
		if (args.length < 1) {
			System.err.println("framework.server.cfg.ServicesCfgHandler expects a file to validate.");
			System.err.println("Usage:");
			System.err.println("framework.server.cfg.ServicesCfgHandler path");
			System.err.println("   where path is the fully path for the agent file to validate.");
			System.exit(1);
		}
		ServicesCfgHandler servicesCfgHandler = new ServicesCfgHandler();
		servicesCfgHandler.parseURI(new File(configurationPath(args[0])));
		servicesCfgHandler.print();
	}
}
